package JaggSoft.Utilidades;

import java.awt.*;
import java.awt.event.*;
import java.util.Calendar;
import javax.swing.*;
import javax.swing.table.*;
import net.sourceforge.jdatepicker.impl.*;

public class Util {
    /**
     * Coloca un selector de fecha en un JPanel y de ser proporcionado tambien otros componentes como JCheckbox, JButton, etc.
     *
     * @param panel panel al cual se colocará el selector de fecha y los componentes suministrados.
     * @param cal (Opcional) calendario por si se requiere utilizar el tipo de calendario personalizado como el de Grecia entre otros, de no necesitarse proporcionar null.
     * @param componentes (Opcional) arreglo de componentes adicionales que se pueden agregar al panel, como: JCheckBox, JButton, JTextField, etc. entre otros, de no necesitarse proporcionar null.
     * @return JDatePickerImpl el cual es un selector de fechas.
     */
    public static JDatePickerImpl ColocarSelectorFecha(JPanel panel,Calendar cal,Component componentes[]){
        JDatePickerImpl selector_fecha;
        panel.setLayout(new FlowLayout());
        for(Component c:componentes){ panel.add(c); }
        UtilDateModel modelo=new UtilDateModel();
        modelo.setSelected(true);
        selector_fecha = new JDatePickerImpl(new JDatePanelImpl(modelo), new DateLabelFormatter());
        panel.add(selector_fecha);
        return selector_fecha;
    }
    /**
     *Indica si un texto es númerico.
     * 
     * @param texto el texto fuente que se verificará si es númerico.
     * @param esDecimal indica si el número es decimal.
     * @return true si es numérico, false de lo contrario.
     */
    public static boolean esNumero(String texto,boolean esDecimal){
        String fuente="0123456789";
        if(!esDecimal){
            for(char c:texto.toCharArray())
                if(!fuente.contains(""+c))
                    return false;
        }
        else{
            int puntos=0;
            for(char c:texto.toCharArray()){
                if(!fuente.contains(""+c)){
                    if(c=='.')
                        puntos++;
                    else
                        return false;
                }
            }
            return (puntos==0||puntos==1);
        }
        return true;
    }
    /**
     *Oculta la columna que se le proporcione en un JTable.
     * 
     * @param tabla la tabla en la cual se ocultara la columna.
     * @param col el número de columna que se ocultara.
     */
    public static void OcultarColumna(JTable tabla,int col){
        tabla.getColumnModel().getColumn(col).setMaxWidth(0);
        tabla.getColumnModel().getColumn(col).setMinWidth(0);
        tabla.getTableHeader().getColumnModel().getColumn(col).setMaxWidth(0);
        tabla.getTableHeader().getColumnModel().getColumn(col).setMinWidth(0);
    }
    /**
     * Carga los datos en un JTable según la consulta que se le proporcione.
     *
     * @param tabla la tabla que se cargaran los datos.
     * @param consulta la consulta con la cuál se cargara la tabla.
     * @param columnas los títulos de las columnas de la tabla, deben tener la misma cantidad de columnas que las de la consulta.
     */
    public static void CargarTabla(JTable tabla,String consulta,String columnas[]){
        Object[] datos=new Object[columnas.length];
        MyModeloTabla modelo=new MyModeloTabla(columnas);
        JTable tmp_tabla=Conexion.ObtenerTabla(consulta,columnas);
        for(int i=0;i<tmp_tabla.getRowCount();i++){
            for(int j=0;j<tmp_tabla.getColumnCount();j++)
                datos[j]=tmp_tabla.getValueAt(i,j);
            modelo.AgregarFila(datos);
        }
        tabla.setModel(modelo);
        datos=null;
        tmp_tabla=null;
    }
    /**
     *Carga los datos en un JTable según la consulta que se le proporcione y lo establece de forma que se puedan editar los campos que se le indiquen.
     * 
     * @param tabla la tabla que contendra los campos editables.
     * @param consulta la consulta de la tabla.
     * @param columnas los títulos de las columnas de la tabla, deben tener la misma cantidad de columnas que las de la consulta.
     * @param cols_edit arreglo booleano que debe tener el mismo tamaño que la cantidad de columnas, el valor de cada elemento del arreglo booleano indica si es editable o no.
     */
    public static void CargarTablaEditable(JTable tabla,String consulta,String columnas[],boolean[] cols_edit){
        Object[] datos=new Object[columnas.length];
        MyModeloTablaEditable modelo=new MyModeloTablaEditable(columnas,cols_edit);
        JTable tmp_tabla=Conexion.ObtenerTabla(consulta,columnas);
        for(int i=0;i<tmp_tabla.getRowCount();i++){
            for(int j=0;j<tmp_tabla.getColumnCount();j++)
                datos[j]=tmp_tabla.getValueAt(i,j);
            modelo.AgregarFila(datos);
        }
        tabla.setModel(modelo);
        datos=null;
        tmp_tabla=null;
    }
    /**
     *Carga un JComboBox según una consulta proporcionada, la consulta debe contener únicamente dos parametros en cual el 1ro obligatoriamente debe ser el id y el 2do la descripción.
     * 
     * @param combo el JComboBox el cuál sera cargado con los datos.
     * @param consulta la consulta que debe tener id y descripción únicamente como campos.
     * @param columnas las columnas con el título de la tabla de la consulta.
     */
    public static void CargarJComboBox(JComboBox<ModeloItemValor> combo,String consulta,String[] columnas){ //Consulta siempre 1ero el ID, 2do la Descripcion
        combo.removeAllItems();
        JTable tabla=Conexion.ObtenerTabla(consulta,columnas);
        for(int i=0;i<tabla.getRowCount();i++)
            combo.addItem(new ModeloItemValor(tabla.getValueAt(i,1),tabla.getValueAt(i,0)));
        tabla=null;
        columnas=null;
    }
    /**
     *Establece el Editor de Celda de un JTable, útil a la hora de obligar a que solo se ingresen números en un campo del JTable. Esto se realiza por tipo de clase de un campo, por ejemplo se puede aplicar para todos los campos Integer, o todos los campos String, etc.
     * 
     * @param tabla la tabla a la cual se le colocara el editor de celda.
     * @param valor_inicial valor por default que tendra la celda.
     * @param clase clase de la celda a las cuales surtira el efecto, ejemplos: Integer.class, String.class, etc.
     */
    public static void ColocarEditorCelda(JTable tabla,String valor_inicial,Class clase){
        JTextField jtf=new JTextField(valor_inicial);
        jtf.setBorder(BorderFactory.createEmptyBorder());
        tabla.setDefaultEditor(clase,new EditorCelda(jtf));
    }
    /**
     *Alinea todas las celdas de un JTable según la alineacion que se proporcione.
     * 
     * @param tabla la tabla a ser alineada.
     * @param alineacion el tipo de alineación, ya sea SwingConstants.LEFT, SwingConstants.RIGHT o SwingConstants.CENTER.
     */
    public static void AlinearColumnas(JTable tabla,int alineacion){
        DefaultTableCellRenderer render=new DefaultTableCellRenderer();
        render.setHorizontalAlignment(alineacion);
        for(int i=0;i<tabla.getColumnCount();i++)
            tabla.getColumnModel().getColumn(i).setCellRenderer(render);
    }
    /**
     *Alinea la celda proporcionada de un JTable según la alineacion que tambien se proporcione.
     * @param tabla  la tabla a ser alineada.
     * @param alineacion el tipo de alineación, ya sea SwingConstants.LEFT, SwingConstants.RIGHT o SwingConstants.CENTER.
     * @param columna la columna a ser alineada.
     */
    public static void AlinearColumna(JTable tabla,int alineacion,int columna){
        DefaultTableCellRenderer render=new DefaultTableCellRenderer();
        render.setHorizontalAlignment(alineacion);
        tabla.getColumnModel().getColumn(columna).setCellRenderer(render);
    }
    /**
     *Habilita la eliminación de filas en un JTable al seleccionar una o mas filas y presionar la tecla DELETE.
     * 
     * @param tabla la tabla a la cual se habilitara la eliminación de filas al presionar la tecla DELETE.
     */
    public static void EstablecerEliminadorFila(JTable tabla){
        InputMap im=tabla.getInputMap(JTable.WHEN_FOCUSED);
        ActionMap am=tabla.getActionMap();
        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,0),"delete");
        am.put("delete",new AccionAbstractaTabla(tabla));
    }
    /**
     *Establece una columna a tipo ComboBox.
     * 
     * @param tabla la tabla que tendra la columna tipo ComboBox.
     * @param columna la columna a la que se le agregara el objeto ComboBox.
     * @param datos arreglo de datos, que tendra el ComboBox.
     */
    public static void EstablecerColumnaCombobox(JTable tabla,int columna,Object[] datos){
        TableColumn col=tabla.getColumnModel().getColumn(columna);
        col.setCellRenderer(new MyRendidorComboBox(datos));
        col.setCellEditor(new MyEditorComboBox(datos));
    }
}